﻿
using RFIDMifare;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Threading;
using System.Windows.Forms;

namespace RfidDriver
{
    public partial class Form1 : Form
    {
        #region 实例化和初始化

        Message message;
        /// <summary>
        /// 实例化卡操作类
        /// </summary>
        private readonly RFIDMifare522 mifare522 = new RFIDMifare522();
        /// <summary>
        /// 实例化状态返回类
        /// </summary>
        Mifare522Result result;
        /// <summary>
        /// 实例化驱动工具类
        /// </summary>
        RFIDMifare522Utils mifare522Utils = new RFIDMifare522Utils();
        // 皮肤库
        Sunisoft.IrisSkin.SkinEngine SkinEngine = new Sunisoft.IrisSkin.SkinEngine();
        List<string> Skins;

        byte[] ReadCarId = new byte[4]; // 读取到的卡号存到这里

        // 发送的命令指令
        string commandInfo = string.Empty;
        string responseInfo = string.Empty;

        public Form1()
        {
            InitializeComponent();
            Skins = Directory.GetFiles(Application.StartupPath + @"\skin\", "*.ssk").ToList();
            SkinEngine.SkinFile = Skins[51]; // 设置默认皮肤
        }
        #endregion

        #region 界面操作

        /// <summary>
        ///  随机更换皮肤按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            //inEngine1.SkinFile = Application.StartupPath + @"\skin\Calmness.ssk";
            // 点击按钮随机更换皮肤
            Random ran = new Random();
            SkinEngine.SkinFile = Skins[ran.Next(0, Skins.Count)];
        }

        /// <summary>
        /// 窗口加载方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            // 扫描串口
            getSport();
            // 默认启动时按钮不可用
            IsButtonEnabled = false;
        }

        /// <summary>
        /// 指示卡操作按钮是否可用
        /// </summary>
        private bool IsButtonEnabled
        {
            set
            {
                // value 是隐式的默认值
                if (value)
                {
                    btn_authKey.Enabled = true;
                    btn_cascAnticoll.Enabled = true;
                    btn_cascSelect.Enabled = true;
                    btn_read.Enabled = true;
                    btn_request.Enabled = true;
                    btn_write.Enabled = true;
                    btn_auth.Enabled = true;
                }
                else
                {
                    btn_authKey.Enabled = false;
                    btn_cascAnticoll.Enabled = false;
                    btn_cascSelect.Enabled = false;
                    btn_read.Enabled = false;
                    btn_request.Enabled = false;
                    btn_write.Enabled = false;
                    btn_auth.Enabled = false;
                }
            }
            get
            {
                // 返回按钮是否可用
                return mifare522.serialPortManager.IsOpen;
            }
        }

        /// <summary>
        /// 弹出消息框
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            if (message == null || message.IsDisposed)//如果消息框没有被打开
            {
                message = new Message();
                message.StartPosition = FormStartPosition.Manual;//窗体显示位置
                message.Location = new Point(this.Right + 20, this.Top);
                message.Show();
            }
            else
            {
                MessageBox.Show("消息框已打开");
            }

        }

        /// <summary>
        /// 点击选择串口的下拉框刷新
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void comboBox1_MouseClick(object sender, MouseEventArgs e)
        {
            getSport();
        }

        /// <summary>
        /// 接收需要显示的信息
        /// </summary>
        /// <param name="cmdType">当前的操作类型</param>
        public void GetShow(string cmdType)
        {
            // 判断状态
            if (!result.Status)
            {
                //显示到界面做准备5
                //转换保存发送的命令
                commandInfo = BitConverter.ToString(result.SendInfo);
                // 转换保存接受到的命令
                responseInfo = BitConverter.ToString(result.ResponseInfo);
                if (!(message == null || message.IsDisposed))//如果消息框被打开
                {
                    message.tb_tishi.AppendText("指令:" + commandInfo + "\r\n");
                    message.tb_tishi.AppendText(cmdType + "失败:" + responseInfo + "\r\n");
                }
                MessageBox.Show(cmdType + "失败");
                return;
            }
            else
            {
                //显示到界面做准备5
                //转换保存发送的命令
                commandInfo = BitConverter.ToString(result.SendInfo);
                // 转换保存接受到的命令
                responseInfo = BitConverter.ToString(result.ResponseInfo);
                if (!(message == null || message.IsDisposed))//如果消息框被打开
                {
                    message.tb_tishi.AppendText("指令:" + commandInfo + "\r\n");
                    message.tb_tishi.AppendText(cmdType + "成功:" + responseInfo + "\r\n");
                }
            }

        }
        #endregion

        #region 串口操作
        /// <summary>
        /// 链接按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bt_lj_Click(object sender, EventArgs e)
        {
            try
            {
                if (bt_lj.Text == "连接")
                {
                    // 串口号不为空
                    if (comboBox1.Items.Count != 0 || comboBox1.Text != string.Empty)
                    {
                        mifare522.PortName = comboBox1.Text;
                        mifare522.Open();
                        // 允许按钮使用
                        IsButtonEnabled = true;

                        text_messageAlert.Text = "串口:" + mifare522.PortName + "打开成功!";
                        bt_lj.Text = "关闭";
                        if (!(message == null || message.IsDisposed))
                        {
                            message.tb_tishi.AppendText("串口:" + mifare522.PortName + "打开成功!" + "\r\n");
                        }
                    }
                    else
                    {
                        MessageBox.Show("未找到串口");
                        return;
                    }
                }
                else
                {
                    mifare522.Close();
                    // 不允许按钮使用
                    IsButtonEnabled = false;
                    bt_lj.Text = "连接";
                    text_messageAlert.Text = "串口:" + mifare522.PortName + "关闭!";
                    if (!(message == null || message.IsDisposed))
                    {
                        message.tb_tishi.AppendText("串口:" + mifare522.PortName + "关闭!" + "\r\n");
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 扫描串口函数
        /// </summary>
        void getSport()
        {
            // 清除串口信息
            comboBox1.Text = string.Empty;
            string[] PortNames = SerialPort.GetPortNames();    //获取本机串口名称，存入PortNames数组中
            comboBox1.DataSource = PortNames;
        }
        #endregion

        #region 卡操作
        /// <summary>
        /// 请求
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_request_Click(object sender, EventArgs e)
        {
            // 读卡请求
            try
            {
                result = mifare522.PiccRequest();
            }
            catch (Exception)
            {

                MessageBox.Show("设备故障");
            }
           
            // 接收需要显示的信息
            GetShow("请求");
        }

        /// <summary>
        /// 防碰撞
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_cascAnticoll_Click(object sender, EventArgs e)
        {
            // 防碰撞
            result = mifare522.AntiCollision();

            // 接收需要显示的信息
            GetShow("防碰撞");

            //ReadCarId = info_jieshou.Substring(12, 11);
            // 保存读取到的卡号用于防碰撞和密钥验证
            ReadCarId = result.Info;
        }

        /// <summary>
        /// 选择
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_cascSelect_Click(object sender, EventArgs e)
        {
            // 选择 赋卡号
            //result = mifare522.Select(RFIDMifare522Utils.HexStringToByteArray(info_jieshou));
            result = mifare522.Select(ReadCarId);
            // 接收需要显示的信息
            GetShow("选择");
        }

        /// <summary>
        /// 验证密钥
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_authKey_Click(object sender, EventArgs e)
        {
            // 验证密钥A
            if (radio_A.Checked)
            {
                // 验证密码 赋卡号 密码 和块
                result = mifare522.AuthenticationKey(ReadCarId, RFIDMifare522Utils.HexStringToByteArray(text_key.Text), Convert.ToInt32(text_block.Text));
            }
            // 验证密钥B
            if (radio_B.Checked)
            {
                // 验证密码 赋卡号 密码 和块
                result = mifare522.AuthenticationKey(ReadCarId, RFIDMifare522Utils.HexStringToByteArray(text_key.Text), Convert.ToInt32(text_block.Text), RFIDMifare522.KeyAB.B);
            }

            // 接收需要显示的信息
            GetShow("密钥验证");
        }

        /// <summary>
        /// 读卡操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_read_Click(object sender, EventArgs e)
        {
            // 读取的块从text_box获取
            result = mifare522.ReadDataBlock(Convert.ToInt32(text_block.Text));

            // 接收需要显示的信息
            GetShow("读卡" + Convert.ToInt32(text_block.Text));
            try
            {
                text_messageAlert.Text = BitConverter.ToString(result.Info).Replace('-', ' ');
            }
            catch (Exception)
            {
                
            }
        }

        /// <summary>
        /// 写入操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_write_Click(object sender, EventArgs e)
        {
            //byte[] writeData = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff};
            byte[] writeData = RFIDMifare522Utils.HexStringToByteArray(text_writeData.Text);
            // 读取的块从界面输入获取
            result = mifare522.WriteDataBlock(Convert.ToInt32(text_block.Text), writeData);

            // 接收需要显示的信息
            GetShow("写入" + Convert.ToInt32(text_block.Text));
        }

        /// <summary>
        /// 写值
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_writeValue_Click(object sender, EventArgs e)
        {
            result = mifare522.WriteValue(Convert.ToInt32(text_block.Text), Convert.ToInt32(text_writeValue.Text));

            // 接收需要显示的信息
            GetShow("写入值块" + Convert.ToInt32(text_block.Text));
            //text_messageAlert.Text = ("写入块" + Convert.ToInt32(text_block.Text) + "：" + BitConverter.ToString(result.Info).Replace('-', ' '));
        }
        /// <summary>
        /// 读值
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_readValue_Click(object sender, EventArgs e)
        {
            result = mifare522.ReadValue(Convert.ToInt32(text_block.Text));

            // 接收需要显示的信息
            GetShow("读取值块" + Convert.ToInt32(text_block.Text));
            text_messageAlert.Text = ("读取块"+ Convert.ToInt32(text_block.Text) + "：" + result.Value);
        }

        
        /// <summary>
        /// 发卡
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_issueCard_Click(object sender, EventArgs e)
        {
            // 存放最后拼接好的数据
            byte[] gather = new byte[16];
            // 金额 将字符串转换为int再将数值转换为byte数组
            byte[] money = RFIDMifare522Utils.ValueTo4Byte(Convert.ToUInt16(text_money.Text), 2);
            // 学号
            byte[] student = RFIDMifare522Utils.ValueTo4Byte(Convert.ToInt32(text_studentNumber.Text), 10);
            // 手机
            byte[] phone = RFIDMifare522Utils.ValueTo4Byte(Convert.ToInt32(text_phone.Text), 4);

            // 素组拼接
            money.CopyTo(gather, 0);
            student.CopyTo(gather, 2);
            phone.CopyTo(gather, 12);

            /// 将数据写入
            byte[] writeData = gather;
            // 读取的块从界面输入获取
            result = mifare522.WriteDataBlock(Convert.ToInt32(text_block.Text), writeData);
            // 接收需要显示的信息
            GetShow("写入" + Convert.ToInt32(text_block.Text));
            
            //E8 03 11 6C 61 71 00 00 00 00 00 00 DD 16 00 00
        }

        /// <summary>
        /// 查询数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_query_Click(object sender, EventArgs e)
        {
            // 读取的块从text_box获取
            result = mifare522.ReadDataBlock(Convert.ToInt32(text_block.Text));
            // 金额
            byte[] money = result.Info.Skip(0).Take(2).ToArray();
            // 学号
            byte[] student = result.Info.Skip(2).Take(10).ToArray();
            // 手机
            byte[] phone = result.Info.Skip(12).Take(4).ToArray();
            // 读取显示
            text_messageAlert.Text = ("读取块" + Convert.ToInt32(text_block.Text) + "：" + RFIDMifare522Utils.BlockDataToValue(money, 2) +
                RFIDMifare522Utils.BlockDataToValue(student, 10) + RFIDMifare522Utils.BlockDataToValue(phone, 4));
        }
       
        /// <summary>
        /// 三合一验证按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_auth_Click(object sender, EventArgs e)
        {
            // 编程式调用点击函数
            //btn_request.PerformClick();
            //btn_cascSelect.PerformClick();
            //btn_cascSelect.PerformClick();
            //btn_authKey.PerformClick();
            try
            {
                // 读卡请求
                result = mifare522.PiccRequest();
               
                // 防碰撞
                result = mifare522.AntiCollision();
                //ReadCarId = info_jieshou.Substring(12, 11);
                // 保存读取到的卡号用于防碰撞和密钥验证
                ReadCarId = result.Info;

                // 空值异常捕获不到的解决方法
                if (ReadCarId == null)
                {
                    throw new ArgumentException("验证失败");
                }

                // 选择 赋卡号
                //result = mifare522.Select(RFIDMifare522Utils.HexStringToByteArray(info_jieshou));
                result = mifare522.Select(ReadCarId);
               
                // 验证密钥A
                if (radio_A.Checked)
                {
                    // 验证密码 赋卡号 密码 和块
                    result = mifare522.AuthenticationKey(ReadCarId, RFIDMifare522Utils.HexStringToByteArray(text_key.Text), Convert.ToInt32(text_block.Text));
                }
                // 验证密钥B
                if (radio_B.Checked)
                {
                    // 验证密码 赋卡号 密码 和块
                    result = mifare522.AuthenticationKey(ReadCarId, RFIDMifare522Utils.HexStringToByteArray(text_key.Text), Convert.ToInt32(text_block.Text), RFIDMifare522.KeyAB.B);
                }
                GetShow("三合一验证");
            }
            catch (Exception)
            {
                MessageBox.Show("验证失败");
            }
        }
        #endregion
    }
}
